﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Text;

namespace WebSpiderLib
{
    public class DotNetWebClient : IWebClient, IDisposable
    {
        // Fields
        private WebClient m_objWebClient;
        private string m_strUserAgent;
        private const string USER_AGENT = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)";

        // Methods
        public DotNetWebClient()
        {
            this.m_strUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)";
        }

        public DotNetWebClient(string userAgent)
        {
            this.m_strUserAgent = userAgent;
        }

        public static string CombineUrl(string baseUrl, string relativeUrl)
        {
            Uri uri = new Uri(new Uri(baseUrl), relativeUrl);
            return uri.AbsoluteUri;
        }

        private WebClient CreateWebClient()
        {
            return new WebClient();
        }

        public void Dispose()
        {
            if (this.m_objWebClient != null)
            {
                this.m_objWebClient.Dispose();
            }
        }

        public byte[] GetBinaryData(string address)
        {
            if (this.m_objWebClient == null)
            {
                this.m_objWebClient = this.CreateWebClient();
            }
            this.m_objWebClient.Headers.Add("user-agent", this.m_strUserAgent);
            return this.m_objWebClient.DownloadData(address);
        }

        public static Encoding GetEncoding(string encodingName)
        {
            switch (encodingName.ToLower())
            {
                case "unicode":
                    return Encoding.Unicode;

                case "utf-7":
                case "utf7":
                    return Encoding.UTF7;

                case "default":
                    return Encoding.Default;

                case "ascii":
                    return Encoding.ASCII;

                case "bigendianunicode":
                    return Encoding.BigEndianUnicode;
            }
            return Encoding.UTF8;
        }

        public string GetWebPageContent(string address, bool replaceHtmlCode, bool throwWebException)
        {
            return this.GetWebPageContent(address, replaceHtmlCode, throwWebException, Encoding.UTF8, "");
        }

        public string GetWebPageContent(string address, bool replaceHtmlCode, bool throwWebException, Encoding encoding)
        {
            return this.GetWebPageContent(address, replaceHtmlCode, throwWebException, encoding, "");
        }

        public string GetWebPageContent(string address, bool replaceHtmlCode, bool throwWebException, Encoding encoding, string referer)
        {
            if (this.m_objWebClient == null)
            {
                this.m_objWebClient = this.CreateWebClient();
            }
            this.m_objWebClient.Headers.Add("user-agent", this.m_strUserAgent);
            this.m_objWebClient.Headers.Add("Referer", referer);
            try
            {
                string htmlContent = Utils.StringFromStream(this.m_objWebClient.OpenRead(address), encoding);
                if (replaceHtmlCode)
                {
                    htmlContent = WebRegEx.HtmlcodeToUnicode(htmlContent);
                }
                return htmlContent;
            }
            catch
            {
                return "";
            }
        }

        public string PostData(string address, NameValueCollection inputValues, bool replaceHtmlCode)
        {
            return this.PostData(address, inputValues, replaceHtmlCode, Encoding.UTF8);
        }

        public string PostData(string address, NameValueCollection inputValues, bool replaceHtmlCode, Encoding encoding)
        {
            try
            {
                if (this.m_objWebClient == null)
                {
                    this.m_objWebClient = this.CreateWebClient();
                }
                this.m_objWebClient.Headers.Add("user-agent", this.m_strUserAgent);
                byte[] bytes = this.m_objWebClient.UploadValues(address, "POST", inputValues);
                string htmlContent = encoding.GetString(bytes);
                if (replaceHtmlCode)
                {
                    htmlContent = WebRegEx.HtmlcodeToUnicode(htmlContent);
                }
                return htmlContent;
            }
            catch (WebException exception)
            {
                return Utils.StringFromStream(exception.Response.GetResponseStream(), encoding);
            }
        }
    }
}
